Skip to content

Conversation

@owen-mc
Copy link
Contributor

@owen-mc owen-mc commented Jan 29, 2026

Note the commit "Fix implementation of barrierNode for barrier models" was needed to make the commit "Convert Flask path-injection sanitizer to MaD" work. I am not certain that it is the correct approach, so please review this carefully.

Also carefully review the MaD that I wrote, as I have no experience with MaD for dynamic languages.

There are two other sanitizers which seemed convertible, but only sanitize certain flow-states. We could in future extend the url-redirection kind string to make it possible to specify this. This would have a much greater benefit if the use of flow states for URL redirection is first implemented for all languages.

Copilot AI review requested due to automatic review settings January 29, 2026 12:13
@owen-mc owen-mc added the no-change-note-required This PR does not need a change note label Jan 29, 2026
@owen-mc owen-mc requested a review from a team as a code owner January 29, 2026 12:13
@owen-mc owen-mc requested review from a team as code owners January 29, 2026 12:17
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enables models-as-data (MaD) sanitizers for Python security queries and converts the Flask path-injection sanitizer from CodeQL to a MaD model. The key change is fixing the barrierNode implementation to use asSink() instead of asSource(), which correctly identifies where data flows into sanitizing functions.

Changes:

  • Fixed barrierNode implementation in ApiGraphModels.qll to use asSink() for proper barrier node identification
  • Converted Flask send_from_directory filename sanitizer from CodeQL class to MaD YAML model
  • Added SanitizerFromModel classes across 8 security query customization files to support MaD-defined sanitizers
  • Added CredentialSanitizer class in HardcodedCredentials.ql to support credential-specific MaD sanitizers

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated no comments.

Show a summary per file
File Description
python/ql/lib/semmle/python/frameworks/data/internal/ApiGraphModels.qll Fixed barrierNode to use asSink() instead of asSource() for correct identification of nodes where data flows into barriers
python/ql/lib/semmle/python/frameworks/Flask.qll Removed FlaskSendFromDirectoryCallFilenameSanitizer class (converted to MaD)
python/ql/lib/semmle/python/frameworks/Flask.model.yml Added MaD barrier model for Flask send_from_directory filename argument
python/ql/lib/semmle/python/security/dataflow/UrlRedirectCustomizations.qll Clarified comment that SanitizerFromModel sanitizes all flow states
python/ql/lib/semmle/python/security/dataflow/UnsafeDeserializationCustomizations.qll Added SanitizerFromModel class for unsafe-deserialization kind
python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll Added SanitizerFromModel class for sql-injection kind
python/ql/lib/semmle/python/security/dataflow/ReflectedXSSCustomizations.qll Added SanitizerFromModel class for html-injection and js-injection kinds
python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll Added SanitizerFromModel class for path-injection kind
python/ql/lib/semmle/python/security/dataflow/LogInjectionCustomizations.qll Added SanitizerFromModel class for log-injection kind
python/ql/lib/semmle/python/security/dataflow/CommandInjectionCustomizations.qll Added SanitizerFromModel class for command-injection kind
python/ql/lib/semmle/python/security/dataflow/CodeInjectionCustomizations.qll Added SanitizerFromModel class for code-injection kind
python/ql/src/Security/CWE-798/HardcodedCredentials.ql Added CredentialSanitizer class to support MaD barriers for credential sinks

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@owen-mc owen-mc force-pushed the python/convert-sanitizers-to-mad branch from fbf9d1d to 7232568 Compare January 29, 2026 16:16

Check warning

Code scanning / CodeQL

Query test without inline test expectations Warning test

Query test does not use inline test expectations.

Check warning

Code scanning / CodeQL

Query test without inline test expectations Warning test

Query test does not use inline test expectations.
Comment on lines +1 to +2
query: Security/CWE-089/SqlInjection.ql
postprocess: utils/test/PrettyPrintModels.ql

Check warning

Code scanning / CodeQL

Query test without inline test expectations Warning test

Query test does not use inline test expectations.

Check warning

Code scanning / CodeQL

Query test without inline test expectations Warning test

Query test does not use inline test expectations.
@owen-mc owen-mc force-pushed the python/convert-sanitizers-to-mad branch from 7232568 to a3885cd Compare January 30, 2026 09:28
@owen-mc
Copy link
Contributor Author

owen-mc commented Jan 30, 2026

@aschackmull pointed out that FlaskSendFromDirectoryCallFilenameSanitizer is really trying to act as an exclusion from the sink definition, which explains why it doesn't work as a MaD sanitizer. The last commit removes it and introduces an extra predicate on FileSystemAccess which specifies arguments which are safe from path injection. This is optional, but I feel like it's a nicer way of doing it.

tausbn
tausbn previously approved these changes Jan 30, 2026
Copy link
Contributor

@tausbn tausbn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One comment, otherwise this looks good to me!

Comment on lines 60 to 61
this = any(FileSystemAccess e).getAPathArgument() and
not this = any(FileSystemAccess e).getASafePathArgument() and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it would make sense to also add getAnUnsafePathArgument to FileSystemAccess, with an implementation consisting of (essentially) these two lines.

That way, the next time we write a query that depends on FileSystemAccess, it's (hopefully) harder to accidentally forget to filter out the safe path arguments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. That makes me think, maybe instead of getASafePathArgument with default none() would could have getAnUnsafePathArgument with default getAPathArgument() and use that in the path injection query.

@owen-mc owen-mc changed the title Python: Allow models-as-data sanitizers and convert 1 existing sanitizer Python: Allow models-as-data sanitizers Jan 30, 2026
@owen-mc owen-mc merged commit 5204255 into github:main Jan 30, 2026
19 checks passed
@owen-mc owen-mc deleted the python/convert-sanitizers-to-mad branch January 30, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-change-note-required This PR does not need a change note Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants